package com.example.gulimall.order.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.core.ResolvableType;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
 * <p>
 *      自定义 bean 获取的行为
 *
 *      既能得到 BeanFactory 的实例，又能得到 BeanFactory 的行为
 * </p>
 *
 * @author zyred
 * @since v 0.1
 **/
@Slf4j
@Component
public class GuLiMallBeanFactory implements BeanFactory{

    public static BeanFactory factory = null;

    public static void setBean(BeanFactory factory) {
        GuLiMallBeanFactory.factory = factory;
        log.info("GuLiMallBeanFactory static field init: [{}]............. ", factory.getClass().getName());
    }


    @NonNull
    @Override
    public <T> T getBean(@NonNull Class<T> clazz) throws BeansException {
        log.info("Method getBean run, target class: {}.", clazz.getName());
        return factory.getBean(clazz);
    }


    @NonNull
    @Override
    public Object getBean(@NonNull String name) throws BeansException {
        return factory.getBean(name);
    }

    @NonNull
    @Override
    public <T> T getBean(@NonNull String name, @NonNull Class<T> requiredType) throws BeansException {
        return factory.getBean(name, requiredType);
    }

    @NonNull
    @Override
    public Object getBean(@NonNull String name, @NonNull Object... args) throws BeansException {
        return factory.getBean(name, args);
    }

    @NonNull
    @Override
    public <T> T getBean(@NonNull Class<T> requiredType, @NonNull Object... args) throws BeansException {
        return factory.getBean(requiredType, args);
    }

    @NonNull
    @Override
    public <T> ObjectProvider<T> getBeanProvider(@NonNull Class<T> requiredType) {
        return factory.getBeanProvider(requiredType);
    }

    @NonNull
    @Override
    public <T> ObjectProvider<T> getBeanProvider(@NonNull ResolvableType requiredType) {
        return factory.getBeanProvider(requiredType);
    }

    @Override
    public boolean containsBean(@NonNull String name) {
        return factory.containsBean(name);
    }

    @Override
    public boolean isSingleton(@NonNull String name) throws NoSuchBeanDefinitionException {
        return factory.isSingleton(name);
    }

    @Override
    public boolean isPrototype(@NonNull String name) throws NoSuchBeanDefinitionException {
        return factory.isPrototype(name);
    }

    @Override
    public boolean isTypeMatch(@NonNull String name, @NonNull ResolvableType typeToMatch) throws NoSuchBeanDefinitionException {
        return factory.isTypeMatch(name, typeToMatch);
    }

    @Override
    public boolean isTypeMatch(@NonNull String name, @NonNull Class<?> typeToMatch) throws NoSuchBeanDefinitionException {
        return factory.isTypeMatch(name, typeToMatch);
    }

    @NonNull
    @Override
    public Class<?> getType(@NonNull String name) throws NoSuchBeanDefinitionException {
        return Objects.requireNonNull(factory.getType(name));
    }

    @NonNull
    @Override
    public String[] getAliases(@NonNull String name) {
        return factory.getAliases(name);
    }
}
